/*
 * GL2DTest.hpp
 *
 *  Created on: Jun 25, 2012
 *      Author: Scorpion
 */

#ifndef GL2DTEST_HPP_
#define GL2DTEST_HPP_
#include <Windows.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <math.h>
#include <time.h>
#ifdef WIN32
#define usleep Sleep
#endif
#define WIN_W 640.0f
#define WIN_H 416.0f
void display(void) {
	glClear(GL_COLOR_BUFFER_BIT);
	//draw points.
#define POINT_DIS 50.0
	glPointSize(2.0);
	glColor3f(1.0, 0.0, 0.0);
	glBegin(GL_POINTS);
	glVertex2f(POINT_DIS, POINT_DIS);
	glVertex2f(POINT_DIS, WIN_H - POINT_DIS);
	glVertex2f(WIN_W - POINT_DIS, WIN_H - POINT_DIS);
	glVertex2f(WIN_W - POINT_DIS, POINT_DIS);
	glEnd();
	//draw lines.
	glLineWidth(1.0);
	glColor3f(0.0, 1.0, 0.0);
	glLineStipple(2, 0xcccc);
	glBegin(GL_LINE_LOOP);
	glVertex2f(2 * POINT_DIS, POINT_DIS);
	glVertex2f(POINT_DIS, 2 * POINT_DIS);
	glVertex2f(POINT_DIS, WIN_H - 2 * POINT_DIS);
	glVertex2f(2 * POINT_DIS, WIN_H - POINT_DIS);
	glVertex2f(WIN_W - 2 * POINT_DIS, WIN_H - POINT_DIS);
	glVertex2f(WIN_W - POINT_DIS, WIN_H - 2 * POINT_DIS);
	glVertex2f(WIN_W - POINT_DIS, 2 * POINT_DIS);
	glVertex2f(WIN_W - 2 * POINT_DIS, POINT_DIS);
	glEnd();
	//draw triangle.
	glEnable(GL_POLYGON_STIPPLE);
	GLubyte fly[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
			0x03, 0x80, 0x01, 0xC0, 0x06, 0xC0, 0x03, 0x60, //
			0x04, 0x60, 0x06, 0x20, 0x04, 0x30, 0x0C, 0x20, //
			0x04, 0x18, 0x18, 0x20, 0x04, 0x0C, 0x30, 0x20, //
			0x04, 0x06, 0x60, 0x20, 0x44, 0x03, 0xC0, 0x22, //
			0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, //
			0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, //
			0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, //
			0x66, 0x01, 0x80, 0x66, 0x33, 0x01, 0x80, 0xCC, //
			0x19, 0x81, 0x81, 0x98, 0x0C, 0xC1, 0x83, 0x30, //
			0x07, 0xe1, 0x87, 0xe0, 0x03, 0x3f, 0xfc, 0xc0, //
			0x03, 0x31, 0x8c, 0xc0, 0x03, 0x33, 0xcc, 0xc0, //
			0x06, 0x64, 0x26, 0x60, 0x0c, 0xcc, 0x33, 0x30, //
			0x18, 0xcc, 0x33, 0x18, 0x10, 0xc4, 0x23, 0x08, //
			0x10, 0x63, 0xC6, 0x08, 0x10, 0x30, 0x0c, 0x08, //
			0x10, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x08 };
	glPolygonStipple(fly);
	glRectf(0.0, 0.0, 32, 32);
	glRectf(0.0, WIN_H - 32, 32, WIN_H);
	glRectf(WIN_W - 32, WIN_H - 32, WIN_W, WIN_H);
	glRectf(WIN_W - 32, 0.0, WIN_W, 32);
	glDisable(GL_POLYGON_STIPPLE);
	//polygon mode.
	glEnable(GL_POLYGON_MODE);
	glEnable(GL_CULL_FACE);
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glCullFace(GL_FRONT);
	glBegin(GL_POLYGON);
#define RT_W 240
#define RT_H 240
	glVertex2f((WIN_W - RT_W) / 2, (WIN_H - RT_H) / 2);
	glVertex2f((WIN_W - RT_W) / 2, (WIN_H + RT_H) / 2);
	glVertex2f((WIN_W + RT_W) / 2, (WIN_H + RT_H) / 2);
	glVertex2f((WIN_W + RT_W) / 2, (WIN_H - RT_H) / 2);
	glEnd();
	glDisable(GL_POLYGON_MODE);
	glDisable(GL_CULL_FACE);
	//the edge flag.
	glBegin(GL_TRIANGLES);
//	glEdgeFlag(GL_FALSE);
	glColor3f(1.0,0.0,0.0);
	glVertex2f(80,20);
//	glEdgeFlag(GL_TRUE);
	glColor3f(0.0,0.0,1.0);
	glVertex2f(WIN_W-80,20);
//	glEdgeFlag(GL_TRUE);
	glColor3f(0.0,1.0,0.0);
	glVertex2f(WIN_W/2,50);
	glEnd();
	//
//	glutSolidSphere(100,4,5);
	//
	glFlush();
}

void init() {
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glColor3f(1.0, 1.0, 0.0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0, WIN_W, 0.0, WIN_H, 0.0, WIN_H);
	glShadeModel(GL_SMOOTH);
	glEnable(GL_LINE_STIPPLE);
	glViewport(0, 0, WIN_W, WIN_H);
}

int dpdmain(int argc, char** argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(WIN_W, WIN_H);
	glutInitWindowPosition(0, 0);
	glutCreateWindow("simple");
	glutDisplayFunc(display);
	init();
	const GLubyte* version=glGetString(GL_VERSION);
	printf("the current OpenGL version:%s\n",version);
	glutMainLoop();
	return 0;
}
///////////////////////////////////////////////////////////////////////////////

void flydisplay(void) {
	GLubyte fly[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
			0x03, 0x80, 0x01, 0xC0, 0x06, 0xC0, 0x03, 0x60, //
			0x04, 0x60, 0x06, 0x20, 0x04, 0x30, 0x0C, 0x20, //
			0x04, 0x18, 0x18, 0x20, 0x04, 0x0C, 0x30, 0x20, //
			0x04, 0x06, 0x60, 0x20, 0x44, 0x03, 0xC0, 0x22, //
			0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, //
			0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, //
			0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, //
			0x66, 0x01, 0x80, 0x66, 0x33, 0x01, 0x80, 0xCC, //
			0x19, 0x81, 0x81, 0x98, 0x0C, 0xC1, 0x83, 0x30, //
			0x07, 0xe1, 0x87, 0xe0, 0x03, 0x3f, 0xfc, 0xc0, //
			0x03, 0x31, 0x8c, 0xc0, 0x03, 0x33, 0xcc, 0xc0, //
			0x06, 0x64, 0x26, 0x60, 0x0c, 0xcc, 0x33, 0x30, //
			0x18, 0xcc, 0x33, 0x18, 0x10, 0xc4, 0x23, 0x08, //
			0x10, 0x63, 0xC6, 0x08, 0x10, 0x30, 0x0c, 0x08, //
			0x10, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x08 }; //

	GLubyte halftone[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, //
			0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, //
			0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, //
			0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, //
			0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, //
			0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, //
			0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, //
			0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, //
			0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, //
			0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, //
			0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, //
			0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, //
			0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, //
			0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, //
			0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, //
			0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55 }; //

	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0, 1.0, 1.0);

	/*  draw one solid, unstippled rectangle,	*/
	/*  then two stippled rectangles		*/
	glRectf(25.0, 25.0, 125.0, 125.0);
	glEnable(GL_POLYGON_STIPPLE);
	glPolygonStipple(fly);
	glRectf(125.0, 25.0, 225.0, 125.0);
	glPolygonStipple(halftone);
	glRectf(225.0, 25.0, 325.0, 125.0);
	glDisable(GL_POLYGON_STIPPLE);

	glFlush();
}

void flyinit(void) {
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glShadeModel(GL_FLAT);
}

void reshape(int w, int h) {
	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
}

void keyboard(unsigned char key, int x, int y) {
	switch (key) {
	case 27:
		exit(0);
		break;
	}
}

int flymain(int argc, char** argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(WIN_W, WIN_H);
	glutCreateWindow(argv[0]);
	init();
	glutDisplayFunc(flydisplay);
	glutReshapeFunc(reshape);
	glutKeyboardFunc(keyboard);
	glutMainLoop();

	return 0;
}
int tessellate(int argc, char **argv);
int twistm(int argc, char **argv);

//
float idlev;
int last;
void idleDisplay(){
#define CENTER_X 100
#define CENTER_Y 100
#define RECT_W 100
	glClear(GL_COLOR_BUFFER_BIT);
	glBegin(GL_LINE_LOOP);
	glVertex2f(CENTER_X+RECT_W*cos(idlev),CENTER_Y+RECT_W*sin(idlev));
	glVertex2f(CENTER_Y+RECT_W*sin(idlev),CENTER_X-RECT_W*cos(idlev));
	glVertex2f(CENTER_X-RECT_W*cos(idlev),CENTER_Y-RECT_W*sin(idlev));
	glVertex2f(CENTER_Y-RECT_W*sin(idlev),CENTER_X+RECT_W*cos(idlev));
	glEnd();
	glFlush();
	last=glutGet(GLUT_ELAPSED_TIME);
}
void idleInit(){
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glColor3f(1.0, 1.0, 0.0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0, WIN_W, 0.0, WIN_H, 0.0, WIN_H);
	glShadeModel(GL_SMOOTH);
	glEnable(GL_LINE_STIPPLE);
	glViewport(0, 0, WIN_W, WIN_H);
	idlev=0;
}
void idleFunc(){
	if((glutGet(GLUT_ELAPSED_TIME)-last)<100){
		usleep(100);
		return;
	}
	idlev+=0.1;
	if(idlev>=2*3.14){
		idlev=0;
	}
	glutPostRedisplay();
}
void menufunc(int v){

}
void smenufunc(int v){

}
void idleMain(int argc,char** argv){
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(WIN_W, WIN_H);
	glutInitWindowPosition(0, 0);
	glutCreateWindow("simple");
	glutDisplayFunc(idleDisplay);
	glutIdleFunc(idleFunc);
	idleInit();
	int smid=glutCreateMenu(smenufunc);
	glutAddMenuEntry("SubLabel-1",1);
	glutAddMenuEntry("SubLabel-2",2);
	int mid=glutCreateMenu(menufunc);
	glutAddMenuEntry("Label-1",1);
	glutAddMenuEntry("Label-2",2);
	glutAddSubMenu("SubLabel",smid);
	glutAttachMenu(GLUT_RIGHT_BUTTON);

	printf("the menu id:%d\n",mid);
	const GLubyte* version=glGetString(GL_VERSION);
	printf("the current OpenGL version:%s\n",version);
	glutMainLoop();
}
//
int sdmain(int argc, char** argv);
//
int cubemain(int argc,char** argv);
//
void acubemain(int argc, char **argv);
//
void gl2dmain(int argc, char **argv) {
	//dpdmain(argc, argv);
	idleMain(argc, argv);
//	tessellate(argc,argv);
//	twistm(argc,argv);
//	sdmain(argc,argv);
//	cubemain(argc,argv);
	//acubemain(argc,argv);
}
#endif /* GL2DTEST_HPP_ */
